package com.example.admin.config;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.admin.util.JwtUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.function.Supplier;

@Component
public class TokenAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {

    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext requestAuthorizationContext) {
        //获取request
        HttpServletRequest request = requestAuthorizationContext.getRequest();
        //获取用户当前的请求地址
        String requestURI = request.getRequestURI();
        //获取token
        String token = request.getHeader(HttpHeaders.AUTHORIZATION);
        if(null == token || "".equals(token)){
            return new AuthorizationDecision(false);
        }
        //解析token
        DecodedJWT decodedJWT = JwtUtils.verify(token);
        SecurityUser securityUser = JwtUtils.parse(decodedJWT, SecurityUser.class);
        if (securityUser == null) {
            //token失效
            return new AuthorizationDecision(false);
        }
        Collection<? extends GrantedAuthority> authorities = securityUser.getAuthorities();
        //存入上下文
        UsernamePasswordAuthenticationToken authenticationToken
                = new UsernamePasswordAuthenticationToken(securityUser, securityUser.getPassword(), authorities);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        //判断地址与对象中的角色是否匹配
        if (authorities.contains(requestURI)) {
            return new AuthorizationDecision(true);
        }
        return new AuthorizationDecision(true);
    }
}
